/**
 * MIT License
 * 
 * Copyright (c) 2024 - present @ ebraid
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */


#ifndef __EB_MATH_H__
#define __EB_MATH_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <types.h>


#define eb_min(a, b) ((a) < (b) ? (a) : (b))
#define eb_min3(a, b, c) (eb_min(eb_min(a,b), c))
#define eb_min4(a, b, c, d) (eb_min(eb_min(a,b), eb_min(c,d)))


#define eb_max(a, b) ((a) > (b) ? (a) : (b))
#define eb_max3(a, b, c) (eb_max(eb_max(a,b), c))
#define eb_max4(a, b, c, d) (eb_max(eb_max(a,b), eb_max(c,d)))

#define eb_clamp(min, val, max) (eb_max(min, (eb_min(val, max))))

#define eb_abs(x) ((x) > 0 ? (x) : (-(x)))


/**
 * @brief calculate sin value by round angle
 * 
 * @param angle  angle of round, should be in [0,360]
 * 
 * @return sin value, should be in [-32768, 32768]
*/
int32_t eb_trigo_sin(int16_t angle);


/**
 * @brief calculate cos value by round angle
 * 
 * @param angle  angle of round, should be in [0,360]
 * 
 * @return cos value, should be in [-32768, 32768]
*/
int32_t eb_trigo_cos(int16_t angle);


/**
 * @brief calculate square root
 * 
 * @param square source
 * 
 * @return value of square root
*/
uint16_t eb_sqrt(uint32_t x);


/**
 * @brief Calculate the angle based on the x and y coordinates. This function is a fast algorithm 
 *        implementation, with reference address: www.RomanBlack.com (Fast XY vector to integer degree algorithm)
 * 
 * @param x:  The x coordinate on a circle
 * @param y:  The y coordinate on a circle
 * 
 * @return angle
*/
uint16_t eb_fast_atan2(int x, int y);


/**
 * @brief To calculate the nth power of x is to find the result of multiplying x by itself n times. 
 *        This operation is often denoted as x^n, where x is the base and n is the exponent. In other words, 
 *        to raise x to the power of n is to perform the operation x multiplied by itself n times.
 * @note  This function uses binary exponentiation, which is a fast exponentiation algorithm
 * 
 * @param x: base
 * @param n: nth power
 * 
 * @return result
*/
uint64_t eb_pow(uint64_t x, uint64_t n);


#ifdef __cplusplus
}
#endif

#endif //__EB_MATH_H__